<script setup lang="ts">
import { ref, onMounted, onUnmounted } from "vue";
import { IconVolume } from "@/components/icons";

const volume = defineModel<number>({ default: 0.6 });

const showVolumeControl = ref(false);
const volumeControlRef = ref<HTMLElement | null>(null);
const volumeButtonRef = ref<HTMLElement | null>(null);
const isDragging = ref(false);
const previousVolume = ref(volume.value);

const handleVolumeChange = (event: MouseEvent) => {
  event.stopPropagation();
  const volumeBar = event.currentTarget as HTMLElement;
  const rect = volumeBar.getBoundingClientRect();
  let percent = 1 - (event.clientY - rect.top) / rect.height;
  percent = Math.max(0, Math.min(1, percent));
  volume.value = percent;
};

const handleVolumeMouseDown = (event: MouseEvent) => {
  isDragging.value = true;
  document.addEventListener("mousemove", handleVolumeMouseMove);
  document.addEventListener("mouseup", handleVolumeMouseUp);
  // 获取初始点击位置的音量值
  const volumeBar = event.currentTarget as HTMLElement;
  const rect = volumeBar.getBoundingClientRect();
  let percent = 1 - (event.clientY - rect.top) / rect.height;
  percent = Math.max(0, Math.min(1, percent));
  volume.value = percent;
};

const handleVolumeMouseMove = (event: MouseEvent) => {
  if (isDragging.value && volumeControlRef.value) {
    const volumeBar = volumeControlRef.value.querySelector(
      ".volume-bar"
    ) as HTMLElement;
    if (volumeBar) {
      const rect = volumeBar.getBoundingClientRect();
      let percent = 1 - (event.clientY - rect.top) / rect.height;
      percent = Math.max(0, Math.min(1, percent));
      volume.value = percent;
    }
  }
};

const handleVolumeMouseUp = () => {
  isDragging.value = false;
  document.removeEventListener("mousemove", handleVolumeMouseMove);
  document.removeEventListener("mouseup", handleVolumeMouseUp);
};

const toggleVolumeControl = (event: MouseEvent) => {
  event.stopPropagation();
  showVolumeControl.value = !showVolumeControl.value;
};

const handleClickOutside = (event: MouseEvent) => {
  if (
    volumeControlRef.value &&
    !volumeControlRef.value.contains(event.target as Node) &&
    volumeButtonRef.value &&
    !volumeButtonRef.value.contains(event.target as Node)
  ) {
    showVolumeControl.value = false;
  }
};

const handleVolumeButtonClick = (event: MouseEvent) => {
  event.stopPropagation();
  showVolumeControl.value = !showVolumeControl.value;
};

onMounted(() => {
  document.addEventListener("click", handleClickOutside);
});

onUnmounted(() => {
  document.removeEventListener("click", handleClickOutside);
});
</script>

<template>
  <div class="relative">
    <button ref="volumeButtonRef" class="p-2" @click="handleVolumeButtonClick">
      <IconVolume
        class="w-5 h-5 transition-opacity"
        :class="{ 'opacity-50': volume === 0 }"
      />
    </button>
    <div
      v-show="showVolumeControl"
      ref="volumeControlRef"
      class="absolute bottom-full left-1/2 -translate-x-1/2 mb-2 p-3 bg-white shadow-lg rounded-lg"
    >
      <div
        class="volume-bar w-1 h-24 bg-gray-200 rounded-full cursor-pointer"
        @mousedown="handleVolumeMouseDown"
      >
        <div
          class="w-full bg-red-500 rounded-full"
          :style="{
            height: `${volume * 100}%`,
            position: 'absolute',
            bottom: 0,
          }"
        >
          <div
            class="absolute top-0 left-1/2 w-3 h-3 bg-white rounded-full shadow-md border border-red-500 -translate-y-1/2 -translate-x-1/2"
          ></div>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.volume-bar {
  position: relative;
}
</style>
